home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: MegaDisc
/
MegaDisc 45 (1996-03)(MegaDisc Digital Publishing)(AU)(Disk 1 of 2)[WB].zip
/
MegaDisc 45 (1996-03)(MegaDisc Digital Publishing)(AU)(Disk 1 of 2)[WB].adf
/
arexx
/
Circular
/
Circular.rexx
< prev
next >
Wrap
OS/2 REXX Batch file
|
1995-08-18
|
18KB
|
454 lines
/* Circles and Things */
/* by John Collett */
signal on syntax ; signal on error
/* Handy escape if things go wrong */
if arg() ~= 0 then signal Finish
/* Open libs */
l.1 = 'rexxsupport.library' ; l.2 = 'rexxarplib.library'
l.3 = 'rexxmathlib.library'
if ~exists('LIBS:' || l.3) then do
say "Sorry. " || l.3 || " needed." ; exit ; end
do i = 1 to 3 ; if ~show('L',l.i) then check = addlib(l.i,0,-30,0)
end
/* Open screen */
call OpenScreen(0,4,HIRES,"",S,"121213102",640,255)
/* Prep window, etc. */
address AREXX '"call CreateHost(W, PORT, S)"'
if ~show('Ports',W) then address command 'WaitForPort W'
flags = 'BORDERLESS + WINDOWCLOSE + WINDOWSIZE + WINDOWDRAG'
idcmp = 'CLOSEWINDOW+GADGETUP+VANILLAKEY'
call OpenWindow(W,0,0,640,255,idcmp,flags)
call openport(PORT) ; call ActivateWindow(W)
call rect(20,1,640,8,0) ; call palet()
call ModifyHost(W,'VANILLAKEY','%l %c %x %y')
call SetReqColor(W,BOXPEN,2)
call AddGadget(W,570,230,1,"Next",'%l %d')
call AddGadget(W,570,244,2,"List",'%l %d')
PI = 3.14159265359 ; twoPi = PI*2
scrno = 1 ; call Screen1()
/* Loop here until Close */
do forever
call waitpkt(PORT) ; pkt = getpkt(PORT)
if pkt ~== NULL() then do
received = getarg(pkt) ; ack = reply(pkt, 0)
parse var received arg1 arg2 arg3
select
when arg1 = 'VANILLAKEY' then do
a = arg2-48 ; if (a=49) | (a=17) then a = 10
if a>0 & a<11 then do
scrno = a ; call GoScreen() ; end
end
when arg1 = 'GADGETUP' then do
if arg2 = 1 then do
if scrno < 10 then scrno = scrno + 1 ; else scrno = 1
call GoScreen()
end
else call ShowList()
end
when arg1 = 'CLOSEWINDOW' then signal 'Finish'
otherwise
end /* of 'select' */
end /* of 'if ... then do' */
end /* of 'do forever' */
Finish:
call CloseWindow(W)
r = CloseScreen(S)
exit
/* Error trapping */
syntax: say 'Syntax : ' errortext(rc) '. Line 'sigl ; signal 'Finish'
error: say "Error " rc sigl ; signal 'Finish'
/* ----- User-defined functions from here on down ----- */
GoScreen:
call rect(0,10,640,255,0) ; call RefreshGadgets(W)
select
when scrno = 1 then call Screen1()
when scrno = 2 then call Screen2()
when scrno = 3 then call Screen3()
when scrno = 4 then call Screen4()
when scrno = 5 then call Screen5()
when scrno = 6 then call Screen6()
when scrno = 7 then call Screen7()
when scrno = 8 then call Screen8()
when scrno = 9 then call Screen9()
when scrno = 10 then call Screen10()
otherwise
end
return
ShowList:
a = "You can go to the next screen by clicking the 'Next' gadget.",
"\After 10, you'll go back to 1. Use the 'Close' gadget to quit.",
"\If, instead of 'Next', you press a number key in the range",
"\1 - 9 (A for 10), you will go directly to that screen.",
"\Screen topics are : ",
"\\ 1 Circles 6 Segments",
"\ 2 Polygons 7 Cylinders",
"\ 3 Arcs (1) 8 Globes",
"\ 4 Arcs (2) 9 Ellipticals",
"\ 5 Sectors A (or a) Arguments"
r = Request(40,90,a,,"Okay",,S) ; call rect(20,1,640,8,0)
return
pat:
call APen(arg(4)) ; call Move(W,arg(1),arg(2)) ; call Text(W,arg(3))
return
box:
call APen(arg(5)) ; call Move(W,arg(1),arg(2))
call Draw(W,arg(3),arg(2)) ; call Draw(W,arg(3),arg(4))
call Draw(W,arg(1),arg(4)) ; call Draw(W,arg(1),arg(2))
return
rect:
call APen(arg(5)) ; call RectFill(W,arg(1),arg(2),arg(3),arg(4))
return
APen: call SetAPen(W,arg(1)) ; return
palet:
call SetRGB4(W,0,6,9,13) ; call SetRGB4(W,1,0,0,6)
call SetRGB4(W,2,15,15,15) ; call SetRGB4(W,3,15,9,4)
call SetRGB4(W,4,15,0,0) ; call SetRGB4(W,5,0,11,0)
call SetRGB4(W,6,0,7,15) ; call SetRGB4(W,7,15,15,0)
do i = 8 to 15 ; j = i - 2 ; call SetRGB4(W,i,j,j,j) ; end
return
/* ---------- Presentation screens ---------- */
Screen1:
a = " Circles and Things",
"\\ Circles and ellipses, with a variety of fillings, can",
"\ be produced easily and quickly by using the 'rexxarplib'",
"\ DrawEllipse, AreaEllipse, and AreaEnd functions."
call WindowText(W,a);call box(140,16,380,28,3);call box(138,15,382,29,1)
do i = 1 to 4
call Apen(i) ; call DrawEllipse(W,100,110,90-i*10,45-i*5) ; end
call Apen(1)
do i = 1 to 15
call AreaEllipse(W,200+20*i,110,20+i*4,30-i)
call AreaEnd(W,2048*(i<8)+i)
end
do i = 1 to 16
call AreaEllipse(W,36*i,170,20+i*2,10+i) ; call AreaEnd(W,2048+255+i)
end
do i = 16 to 1 by -1
call AreaEllipse(W,30+36*i,210,52-i*2,26-i)
call AreaEnd(W,2048+512+i)
end
a="But when you want to move into the trickier area of *parts*",
"\of circles (arcs, chords, sectors, segments, etc.), you",
"\need to develop special functions.",
"\\That's what this program is all about."
r = Request(50,150,a,,"Okay",,S) ; call rect(20,1,640,8,0)
return
Screen2:
a=" The key is to work with polygons rather than circles. With 20",
"\ or more sides they look sufficiently like circles for most",
"\ purposes. Aim at a compromise between speed and smoothness :",
"\ - the more sides (up to 360?), the smoother the circle",
"\ - the fewer sides, the faster the execution, though it will",
"\ never be anything like as fast as the 'rexxarplib' functions.",
"\ Here are a few preliminary exercises."
call WindowText(W,a)
call pat(38,160,"24-sided circle",1) ; call Polygon(90,120,60,30,24,1,1)
call pat(136,238,"Double",1) ; call Polygon(160,200,60,30,10,14,0)
call Polygon(160,200,58,29,5,14,0) ; call pat(188,160,"With spokes",1)
call Spokes(230,120,60,30,24,7,1) ; call pat(270,238,"Rimless",1)
call Spokes(300,200,60,30,24,15,0) ; call pat(330,160,"Plain fill",1)
call Fill(370,120,60,30,12,1,2048+4)
call pat(394,238,"Patterned fill",1)
call Fill(440,200,60,30,8,1,2048+271)
call pat(460,160,"Dithered fill",1)
call Fill(510,120,60,30,6,1,2048+513)
a="You may have noticed that my polygons are all constructed",
"\clock-wise from top-centre. This took a bit of doing,",
"\but was worth it, because it makes it relatively easy to",
"\plan parts of circles, as shown on the following screens."
r = Request(50,150,a,,"Okay",,S) ; call rect(20,1,640,8,0)
return
Screen3:
a = " Arcs",
"\\Details which have to be controlled are their centre, radius,",
"\colour, and span. The programming is a bit nasty if the span",
"\crosses the top centre, but it seems to work.",
"\\The examples below may not constitute a work of art, but the",
"\arcs produced are at least as I intend them to be."
call WindowText(W,a)
call Arc(120,170,100,50,32,1,24,6);call Arc(130,170,90,45,32,1,25,5)
call Arc(140,170,80,40,32,1,24,4) ; call Arc(220,170,100,50,32,2,2,18)
call Arc(210,160,90,45,32,2,4,16) ; call Arc(200,150,80,40,32,2,6,14)
call Arc(160,144,100,50,32,4,10,22);call Arc(170,140,90,45,32,4,12,21)
call Arc(180,136,80,40,32,4,14,20) ;call Arc(450,170,80,40,32,1,20,4)
call Arc(475,183,88,44,32,1,22,2)
call APen(7) ; call Flood(W,1,400,150) ; call APen(1)
a="Whereas a clockface has 12 points of reference, these arcs",
"\have 32 possible reference points, eight per quarter. So '8'",
"\points to 3 o'clock, '16' to 6 o'clock, '24' to 9 o'clock,",
"\and '32' (or '0') to 12 o'clock.",
"\This is as fine a scale as anyone is likely to need."
r = Request(50,150,a,,"Okay",,S) ; call rect(20,1,640,8,0)
return
Screen4:
a="This business of arcs is a bit complicated.",
"\An arc is just a piece of a circle. The arrangement in this",
"\program is that circles are really polygons. Most details for",
"\an arc are determined in the same way as for a complete polygon.",
"\But the *span* of an arc is always based on a 32-sided polygon.",
"\Advantages: Easier to visualise and plan.",
"\ The arithmetic remained manageable (just).",
"\Disadvantage : The beginning and end of the arc MAY not coincide",
"\with the sides of the polygon, but I can't think of any",
"\application where this is likely to be a real inconvenience."
call WindowText(W,a)
call pat(40,200,"Four quarter-circle arcs fit reasonably",2)
call pat(40,209,"well into 32- and 16-sided polygons.",2)
call Spokes(150,160,60,30,32,15,0)
call Arc(150,160,60,30,32,4,0,8) ; call Arc(150,160,60,30,32,1,8,16)
call Arc(150,160,60,30,32,2,16,24);call Arc(150,160,60,30,32,3,24,32)
call Spokes(300,160,60,30,16,15,0)
call Arc(300,160,60,30,16,4,0,8) ; call Arc(300,160,60,30,16,1,8,16)
call Arc(300,160,60,30,16,2,16,24);call Arc(300,160,60,30,16,3,24,32)
call pat(400,200,"With 14 sides, the four",2)
call pat(400,209,"arcs just do not fit.",2)
call Spokes(450,160,60,30,14,15,0)
call Arc(450,160,60,30,14,4,0,8) ; call Arc(450,160,60,30,14,1,8,16)
call Arc(450,160,60,30,14,2,16,24);call Arc(450,160,60,30,14,3,24,32)
return
Screen5:
a="It is a small step from drawing arcs to producing segments of",
"\a circle by adding the chords. Those segments can be filled",
"\in a variety of ways."
call WindowText(W,a)
call Segment(300,90,50,25,32,1,0,11)
call APen(4) ; call Flood(W,1,330,80)
call Segment(300,90,50,25,32,1,11,21)
call APen(6) ; call Flood(W,1,300,110)
call Segment(300,90,50,25,32,1,21,32)
call APen(5) ; call Flood(W,1,260,80)
call APen(2) ; call Flood(W,1,300,90)
do j = 150 to 450 by 150
call FillSegment(j,190,100,50,20,13,27,5,256+6,0)
call Segment(j,190,100,50,20,9,27,5,4,0)
call Segment(j+2,189,100,50,20,15,27,5,4,0)
k=j-86
do p = 1 to 6
call APen(8+p) ; call RectFill(W,k+p*2,160,k+p*2+2,180) ; end
end
k=520
do p = 1 to 6
call APen(8+p) ; call RectFill(W,k+p*2,160,k+p*2+2,180)
end
return
Screen6:
a="\From arcs, chords, and sectors, we move on to segments as used in",
"\a pie chart.",
"\\If you watch it closely, you'll see that I cheat a bit, overlapping",
"\the segments slightly as they are drawn, to give a tidier appearance",
"\to the shared radii."
call WindowText(W,a)
s.1=2;e.1=6 ; s.2=5;e.2=15 ; s.3=14;e.3=20
s.4=19;e.4=23 ; s.5=22;e.5=28 ; s.6=27;e.6=3
do se = 1 to 6
call FillSegment(250,140,100,50,32,3,s.se,e.se,2048+256+5+se,1)
end
do i = 1 to 2
call APen(i+(i>1)) ; call DrawEllipse(W,250,140,100+2*i,50+i)
end
return
Screen7:
a="Now let's boldly try our hand at something three-dimensional.",
"\We had some small pillars supporting a bridge on another screen.",
"\Here is something more ambitious. The foot of each pillar and of",
"\the cone are the interesting bits."
call WindowText(W,a)
call APen(13) ; call Move(W,60,172) ; call Draw(W,70,160)
call Draw(W,465,160) ; call Draw(W,475,172) ; call Draw(W,60,172)
call Flood(W,1,80,170) ; call APen(9) ; call RectFill(W,60,172,475,186)
do pi = 1 to 4 ; call Pillar(pi*100,70,100,24+6*pi,(pi=4)) ; end
return
Screen8:
a="\\ This attempt at globes with a 3D appearance is not all that",
"\ convincing, but at least it is reasonably fast."
call WindowText(W,a)
call Globe(220,140,50,25)
call Globe(320,200,60,30)
return
Screen9:
a=" We'd better just check that the main functions used in this",
"\ program perform as required for ellipses as well as for circles."
call WindowText(W,a)
call Polygon(100,70,60,20,18,1,0) ; call Spokes(100,150,60,40,12,4,1)
call Fill(300,130,30,40,12,1,2048+6);call Arc(300,144,120,100,18,2,2,26)
call Segment(490,90,84,28,24,7,29,11)
call FillSegment(490,170,40,30,16,4,2,25,2048+256+6,0)
call Globe(300,206,60,10)
return
Screen10:
a="The following circle-related functions can be found in the program.",
"\Some parts of the code are frequently duplicated to facilitate the",
"\lifting out of any functions you may wish to use elsewhere.",
"\\ Polygon(x,y,r1,r2,sides,pen)",
"\\ Spokes(x,y,r1,r2,sides,pen,rimflag)",
"\\ Fill(x,y,r1,r2,sides,pen+flags)",
"\ flags : 256 -> pattern ; 512 -> dither ; 2048 -> outlined",
"\\ Arc(x,y,r1,r2,sides,pen,start,finish)",
"\\ Segment(x,y,r1,r2,sides,pen,start,finish)",
"\ ArcBit: Called by 'Arc' and 'Segment'",
"\\ FillSegment(x,y,r1,r2,sides,drawpen,start,finish,fillpen,flag)",
"\ flag = 'segment or sector'",
"\ FillSegBit: Called by 'FillSegment'",
"\\ Pillar(left,top,height,width)",
"\\ Globe(x,y,r1,r2)"
call WindowText(W,a) ; call box(20,50,550,230,7)
return
/* ----- Special polygons : pattern, spoked, alternate ----- */
Polygon:
x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
call APen(arg(6)) ; call Move(W,x,y-r2) ; f = 1 ; step = twoPI/sides
do i = -1.6 to 4.8 by step
co=x+r1*cos(i) ; si=y+r2*sin(i)
if arg(7) = 1 then do ; f = ~f ; call APen(arg(6)+f) ; end
call Draw(W,co,si)
end
return
Spokes:
x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
call APen(arg(6)) ; call Move(W,x,y-r2) ; step = twoPI/sides
do i = -1.6 to 4.8 by step
co=x+r1*cos(i) ; si=y+r2*sin(i)
if arg(7) = 1 then call Draw(W,co,si) ; else call Move(W,co,si)
call Draw(W,x,y) ; call Draw(W,co,si)
end
return
Fill:
x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
call APen(arg(6)) ; call Move(W,x,y-r2) ; call AreaDraw(W,x,y-r2)
step = twoPI/sides
do i = -1.6 to 4.8 by step
co=x+r1*cos(i) ; si=y+r2*sin(i)
call Draw(W,co,si) ; call AreaDraw(W,co,si)
end
call AreaEnd(W,arg(7))
return
/* ------------ Shapes and Pieces ----------- */
Arc:
x=arg(1) ; y=arg(2) ; r1 = arg(3) ; r2 = arg(4) ; sides = arg(5)
call APen(arg(6)) ; st = arg(7) ; f = arg(8)
if st > f then do ; call ArcBit(st,32) ; call ArcBit(0,f) ; end
else call ArcBit(st,f)
return
ArcBit: /* Called by 'Arc' and 'Segment' */
step = twoPI/sides
start = (arg(1) - 8)*0.2 ; fin = (arg(2) - 8)*0.2
call Move(W,x+r1*cos(start),y+r2*sin(start))
do i = start to fin by step
co=x+r1*cos(i) ; si=y+r2*sin(i) ; call Draw(W,co,si)
end
return
Segment:
x=arg(1) ; y=arg(2) ; r1=arg(3) ; r2=arg(4) ; sides=arg(5)
call APen(arg(6)) ; st = arg(7) ; f = arg(8)
if st > f then do
call ArcBit(st,32) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
call ArcBit(0,f)
end
else do ;
call ArcBit(st,f) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
end
call Draw(W,dx,dy)
return
FillSegBit: /* Called by 'FillSegment' */
start = (arg(1) - 8)*0.2 ; fin = (arg(2) - 8)*0.2
dx = x+r1*cos(start) ; dy = y+r2*sin(start)
call Move(W,dx,dy) ; call AreaDraw(W,dx,dy) ; step = twoPI/sides
do i = start to fin by step
co=x+r1*cos(i) ; si=y+r2*sin(i)
call Draw(W,co,si) ; call AreaDraw(W,co,si)
end
return
FillSegment:
x=arg(1) ; y=arg(2) ; r1=arg(3) ; r2=arg(4) ; sides=arg(5)
call APen(arg(6)) ; st = arg(7) ; f = arg(8) ; patt = arg(9)
SegOrSec = arg(10)
if st > f then do
call FillSegBit(st,32) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
call FillSegBit(0,f)
end
else do ;
call FillSegBit(st,f) ; dx = x+r1*cos(start) ; dy = y+r2*sin(start)
end
if SegOrSec then do ; call Draw(W,x,y) ; call AreaDraw(W,x,y) ; end
call Draw(W,dx,dy) ; call AreaEnd(W,patt)
return
Pillar:
left = arg(1) ; top = arg(2) ; height = arg(3) ; width = arg(4)
cylinder = (arg(5) = 0) ; step = width%8
if cylinder then do p = 0 to 7
call APen(p+8)
call RectFill(W,left+p*step,top,left+p*step+step,top+height)
end
else do p = 0 to 7
call APen(p+8) ; call AreaDraw(W,left+width%2,top)
call AreaDraw(W,left+p*step,top+height)
call AreaDraw(W,left+p*step+step,top+height) ; call AreaEnd(W,p+8)
end
x=left+width/2 ; y = top+height-width%8 ; r1=width%2 ; r2=width%8
call APen(13)
step = twoPI/32 ; call Move(W,x+r1,y+r2) ; call AreaDraw(W,x+r1,y+r2)
do i = 0 to 3.2 by step
co=x+r1*cos(i) ; si=y+r2*sin(i)
call Draw(W,co,si) ; call AreaDraw(W,co,si)
end
call Draw(W,x-r1,y+r2) ; call AreaDraw(W,x-r1,y+r2)
call Draw(W,x+r1,y+r2) ; call AreaDraw(W,x+r1,y+r2)
call AreaEnd(W,13)
return
Globe:
x=arg(1) ; y = arg(2) ; r1 = arg(3) ; r2 = arg(4)
call AreaEllipse(W,x,y,r1,r2) ; call AreaEnd(W,8)
drx = r1%16 ; dry = r2%16
do i = 1 to 7
call AreaEllipse(W,x+i*drx,y-i*dry,r1-i*drx*2,r2-i-i*dry*2)
call AreaEnd(W,8+i)
end
return
/* Hamilton, New Zealand March, 1995 */